package com.mars.foodserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mars.foodserver.constant.Constant;
import com.mars.foodserver.constant.NumberConstant;
import com.mars.foodserver.entity.SysIgnorePath;
import com.mars.foodserver.exception.WorkException;
import com.mars.foodserver.mapper.SysIgnorePathMapper;
import com.mars.foodserver.service.ISysIgnorePathService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * SysIgnorePath 实现层
 *
 * @Author wq
 * @Date 2021-06-12
 **/
@Service
@Slf4j
@SuppressWarnings("all")
@Transactional(rollbackFor = RuntimeException.class)
public class SysIgnorePathServiceImpl extends ServiceImpl<SysIgnorePathMapper, SysIgnorePath> implements ISysIgnorePathService {


    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public List<String> acquirePaths() {
        return baseMapper.selectList(new LambdaQueryWrapper<SysIgnorePath>().
                eq(SysIgnorePath::getDeleted, NumberConstant.ZERO)).stream().
                map(SysIgnorePath::getPath).collect(Collectors.toList());
    }

    @Override
    public Boolean isIgnorePath(String path) {
        List list = redisTemplate.boundListOps(Constant.IGNORE_CACHE_PATH).range(0, -1);
        if (CollectionUtils.isEmpty(list)) {
            //缓存放行路径
            cachePaths();
            //查询数据库中
            SysIgnorePath sysIgnorePath = baseMapper.selectOne(new LambdaQueryWrapper<SysIgnorePath>().
                    eq(SysIgnorePath::getPath, path));
            return Objects.nonNull(sysIgnorePath);
        } else {
            for (Object pathStr : list) {
                return pathStr.toString().indexOf(path) >= 0;
            }
            return false;
        }
    }

    /**
     * 缓存放行路径
     */
    private void cachePaths() {
        BoundListOperations listOps = redisTemplate.boundListOps(Constant.IGNORE_CACHE_PATH);
        if (!redisTemplate.hasKey(Constant.IGNORE_CACHE_PATH)) {
            List<String> paths = this.acquirePaths();
            // 将整个列表存入redis中
            listOps.leftPushAll(paths);
        }
    }

    @Override
    public void add(String path, String description) {
        redisTemplate.delete(Constant.IGNORE_CACHE_PATH);

        if (StringUtils.isEmpty(path)) {
            throw new WorkException("请输入放行路径");
        }
        if (StringUtils.isEmpty(path)) {
            throw new WorkException("请输入描述");
        }
        SysIgnorePath ignorePath = baseMapper.selectOne(new LambdaQueryWrapper<SysIgnorePath>().
                eq(SysIgnorePath::getPath, path).eq(SysIgnorePath::getDescription, description));
        if (Objects.nonNull(ignorePath)) {
            throw new WorkException("该路径已经添加");
        }
        SysIgnorePath sysIgnorePath = new SysIgnorePath();
        sysIgnorePath.setPath(path);
        sysIgnorePath.setDescription(description);
        save(sysIgnorePath);
        //缓存放行路径
        cachePaths();

    }

    @Override
    public void delete(Integer id) {
        baseMapper.deleteById(id);
        redisTemplate.delete(Constant.IGNORE_CACHE_PATH);
        //缓存放行路径
        cachePaths();
    }

}